package clock.socoolby.com.clock.widget.animatorview.animator;

import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;

import java.util.ArrayList;
import java.util.List;

import clock.socoolby.com.clock.widget.animatorview.AbstractAnimator;
import clock.socoolby.com.clock.widget.animatorview.I_AnimatorEntry;


//参考自:https://github.com/chengduboy/android/
public class CarrouselAnimator extends AbstractAnimator<CarrouselAnimator.Carrousel> {

    public static final String NAME="Carrousel";

    public CarrouselAnimator(int entryQuantity) {
        super(entryQuantity);
    }

    public CarrouselAnimator() {
        super(2);
    }

    @Override
    public int delayTime() {
        return 5;
    }

    @Override
    public Carrousel createNewEntry() {
        return new Carrousel(width/2,height/2,rand.nextInt(width),rand.nextInt(90),rand.nextInt(90),rand.nextInt(8));
    }

    public class Carrousel implements I_AnimatorEntry {

        //自动旋转 默认不自动
        private boolean mAutoRotation;

        //旋转间隔时间  默认设置为2秒
        private int mRotationTime;

        //旋转木马旋转半径  圆的半径
        private float mCarrouselR;

        //camera和旋转木马距离
        private float mDistance;

        //旋转方向 分0顺时针和 1逆时针 俯视旋转木马看
        private int mRotateDirection;

        //x旋转
        private int mRotationX;

        //Z旋转
        private int mRotationZ;

        //旋转的角度
        private float mAngle = 0;

        //旋转木马子view
        private List<PointCicle> mCarrouselViews;

        //旋转木马子view的数量
        private int  viewCount;

        //半径扩散动画
        //private ValueAnimator mAnimationR;

        //旋转动画
        //private ValueAnimator restAnimator;

        //x轴旋转动画
        //private ValueAnimator xAnimation;

        //z轴旋转动画
        //private ValueAnimator zAnimation;
        private int mCenterX, mCenterY;

        public Carrousel(int mCenterX,int mCenterY,float mDistance, int mRotationX, int mRotationZ, int viewCount) {
            this.mCenterX=mCenterX;
            this.mCenterY=mCenterY;
            this.mDistance = mDistance;
            this.mRotationX = mRotationX;
            this.mRotationZ = mRotationZ;
            this.viewCount = viewCount;
            init();
        }

        private void init() {
            mAutoRotation=true;
            mRotationTime=2000;
            mRotateDirection=0;
            mCarrouselR=mDistance/2;
            initPointCicle();
            refreshLayout();
        }

        private void initPointCicle(){
            mCarrouselViews=new ArrayList<>();
            for(int i=0;i<viewCount;i++){
                randomColorIfAble();
                mCarrouselViews.add(new PointCicle(rand.nextInt(50),color));
            }
        }


        /**
         * 初始化 计算平均角度后各个子view的位置
         */
        public  void refreshLayout() {
            for (int i=0;i<mCarrouselViews.size();i++){
                double radians = mAngle + 180 - i * 360 / viewCount;
                float x0 = (float) Math.sin(Math.toRadians(radians)) * mCarrouselR;
                float y0 = (float) Math.cos(Math.toRadians(radians)) * mCarrouselR;
                float scale0 = (mDistance - y0) / (mDistance + mCarrouselR);
                mCarrouselViews.get(i).x=x0;
                mCarrouselViews.get(i).y=y0;

                mCarrouselViews.get(i).setScaleX(scale0);
                mCarrouselViews.get(i).setScaleY(scale0);

                float rotationX_y = (float) Math.sin(Math.toRadians(mRotationX * Math.cos(Math.toRadians(radians)))) * mCarrouselR;
                float rotationZ_y = -(float) Math.sin(Math.toRadians(-mRotationZ)) * x0;
                float rotationZ_x = (((float) Math.cos(Math.toRadians(-mRotationZ)) * x0) - x0);

                mCarrouselViews.get(i).setTranslationX(x0 + rotationZ_x);
                mCarrouselViews.get(i).setTranslationY(rotationX_y + rotationZ_y);
            }
        }


        float angleStep=10;
        @Override
        public void move(int maxWidth, int maxHight) {
            mAngle = mAngle+angleStep;
            if(mAngle>360) {
                mAngle = 0;
                mRotationZ+=angleStep/5;
                if(mRotationZ>360)
                    mRotationZ=0;
            }
            //mCarrouselR = (Float) valueAnimator.getAnimatedValue();
            //mRotationX= (Integer) animation.getAnimatedValue();
            //mRotationZ= (Integer) animation.getAnimatedValue();
            refreshLayout();
        }

        @Override
        public void onDraw(Canvas canvas, Paint mPaint) {
            for(PointCicle pointCicle:mCarrouselViews){
                mPaint.setColor(pointCicle.color);
                Matrix matrix=new Matrix();
                matrix.setScale(pointCicle.scaleX,pointCicle.scaleY);
                canvas.setMatrix(matrix);
                //canvas.drawCircle(mCenterX+pointCicle.percent,mCenterY+pointCicle.y,pointCicle.r,mPaint);
                canvas.drawCircle(mCenterX+pointCicle.translationX,mCenterX+pointCicle.translationY,pointCicle.r,mPaint);
            }
        }

        @Override
        public void setAnimatorEntryColor(int color) {
            for(PointCicle pointCicle:mCarrouselViews){
                pointCicle.color=color;
            }
        }

        /**
         * 通过角度计算是第几个item
         *
         * @return
         */
        private int calculateItem() {
            return (int) (mAngle / (360 / viewCount)) % viewCount;
        }


        /**
         * 获取角度
         *
         * @return
         */
        public float getAngle() {
            return mAngle;
        }


        /**
         * 设置角度
         *
         * @param angle
         */
        public void setAngle(float angle) {
            this.mAngle = angle;
        }

        /**
         * 获取距离
         *
         * @return
         */
        public float getDistance() {
            return mDistance;
        }

        /**
         * 设置距离
         *
         * @param distance
         */
        public void setDistance(float distance) {
            this.mDistance = distance;
        }

        /**
         * 获取半径
         *
         * @return
         */
        public float getR() {
            return mCarrouselR;
        }


        /**
         * 设置选中方法
         *
         * @param selectItem
        public void setSelectItem(int selectItem) {
            if (selectItem >= 0) {
                float angle = 0;
                if (getSelectItem() == 0) {
                    if (selectItem == mCarrouselViews.size() - 1) {
                        angle = mAngle - (360 / viewCount);
                    } else {
                        angle = mAngle + (360 / viewCount);
                    }
                } else if (getSelectItem() == mCarrouselViews.size() - 1) {
                    if (selectItem == 0) {
                        angle = mAngle + (360 / viewCount);
                    } else {
                        angle = mAngle - (360 / viewCount);
                    }
                } else {
                    if (selectItem > getSelectItem()) {
                        angle = mAngle + (360 / viewCount);
                    } else {
                        angle = mAngle - (360 / viewCount);
                    }
                }

                float resultAngle = 0;
                float part = 360 / viewCount;
                if (angle < 0) {
                    part = -part;
                }
                //最小角度
                float minvalue = (int) (angle / part) * part;
                //最大角度
                float maxvalue = (int) (angle / part) * part;
                if (angle >= 0) {//分为是否小于0的情况
                    if (angle - mLastAngle > 0) {
                        resultAngle = maxvalue;
                    } else {
                        resultAngle = minvalue;
                    }
                } else {
                    if (angle - mLastAngle < 0) {
                        resultAngle = maxvalue;
                    } else {
                        resultAngle = minvalue;
                    }
                }

                if (viewCount > 0) startAnimRotation(resultAngle, null);
            }
        }*/

        /**
         * 设置半径
         *
         * @param r
         */
        public void setR(float r) {
            this.mCarrouselR = r;
            mDistance = 2f * r;
        }


        /**
         * 设置是否自动切换
         *
         * @param autoRotation
         */
        public void setAutoRotation(boolean autoRotation) {
            this.mAutoRotation = autoRotation;
        }

        /**
         * 获取自动切换时间
         *
         * @return
         */
        public long getAutoRotationTime() {
           return mRotationTime;
        }

        /**
         * 设置自动切换时间间隔
         *
         * @param autoRotationTime
         */
        public void setAutoRotationTime(int autoRotationTime) {
           this.mRotationTime=autoRotationTime;
        }

        /**
         * 是否自动切换
         *
         * @return
         */
        public boolean isAutoRotation() {
            return mAutoRotation;
        }

        //旋转方向
        private CarrouselRotateDirection  mRotateDirection1;

        /**
         * 设置自动选择方向
         * @param mCarrouselRotateDirection
         * @return
         */
        public void setAutoScrollDirection(CarrouselRotateDirection mCarrouselRotateDirection) {
            this.mRotateDirection1=mCarrouselRotateDirection;

        }

        /**
         * 半径扩散、收缩动画 根据设置半径来实现
         * @param from
         * @param to
         */
        public void startAnimationR(float from, float to) {
            /** mAnimationR = ValueAnimator.ofFloat(from, to);
             mAnimationR.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
            mCarrouselR = (Float) valueAnimator.getAnimatedValue();
            refreshLayout();
            }
            });
             mAnimationR.setInterpolator(new DecelerateInterpolator());
             mAnimationR.setDuration(2000);
             mAnimationR.start();
             **/
        }


        /**
         * 动画旋转
         * @param resultAngle
         *
         */
        private void startAnimRotation(float resultAngle) {
            if (mAngle == resultAngle) {
                return;
            }
            /**
             restAnimator = ValueAnimator.ofFloat(mAngle, resultAngle);
             //设置旋转匀速插值器
             restAnimator.setInterpolator(new LinearInterpolator());
             restAnimator.setDuration(300);
             restAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
            if (isTouching == false) {
            mAngle = (Float) animation.getAnimatedValue();
            refreshLayout();
            }
            }
            });**/

        }

        /**
        public void createXAnimation(int from, int to, boolean start){
            if(xAnimation!=null)if(xAnimation.isRunning()==true)xAnimation.cancel();
            xAnimation= ValueAnimator.ofInt(from,to);
            xAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mRotationX= (Integer) animation.getAnimatedValue();
                    refreshLayout();
                }
            });
            xAnimation.setInterpolator(new LinearInterpolator());
            xAnimation.setDuration(2000);
            if(start)xAnimation.start();
        }


        public ValueAnimator createZAnimation(int from, int to, boolean start){
            if(zAnimation!=null)if(zAnimation.isRunning()==true)zAnimation.cancel();
            zAnimation= ValueAnimator.ofInt(from,to);
            zAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mRotationZ= (Integer) animation.getAnimatedValue();
                    refreshLayout();
                }
            });
            zAnimation.setInterpolator(new LinearInterpolator());
            zAnimation.setDuration(2000);
            if(start)zAnimation.start();
            return zAnimation;
        }**/

        public void setRotationX(int mRotationX) {
            this.mRotationX = mRotationX;
        }

        public void setRotationZ(int mRotationZ) {
            this.mRotationZ = mRotationZ;
        }

        public float getRotationX() {
            return mRotationX;
        }

        public int getRotationZ() {
            return mRotationZ;
        }
    }

    public class PointCicle{
        float x,y;
        int r;
        float scaleX,scaleY,translationX,translationY;
        int color;

        public PointCicle(int r, int color) {
            this.r = r;
            this.color = color;
        }

        public void setScaleX(float scale0) {
            this.scaleX=scale0;
        }

        public void setScaleY(float scale0) {
            this.scaleY=scale0;
        }

        public void setTranslationX(float translationX){
            this.translationX=translationX;
        }

        public void setTranslationY(float translationy){
           this.translationY=translationy;
        }
    }

    /**
     * 旋转木马旋转方向
     * Created by dalong on 2016/11/12.
     */

    public enum CarrouselRotateDirection {
        clockwise, //顺时针方向
        anticlockwise //逆时针方向
    }
}
